package datastruct.dict.impl;

import datastruct.dict.inter.IDict;
import datastruct.dict.inter.IDictConsumer;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class JoSimpleMap implements IDict {
    private HashMap<String, Object> hm;

    public JoSimpleMap() {
        hm = new HashMap<>();
    }

    @Override
    public Object get(String key) {
        return hm == null || hm.size()==0 ? null : hm.get(key);
    }

    @Override
    public int len() {
        return hm == null ? 0 : hm.size();
    }

    @Override
    public int put(String key, Object val) {
        if (hm == null) {
            return 0;
        }
        if (hm.containsKey(key)) {
            hm.put(key, val);
            return 0;
        }
        hm.put(key, val);
        return 1;
    }


    public boolean contains(String key) {
        return hm != null && hm.containsKey(key);
    }

    @Override
    public int putIfAbsent(String key, Object val) {
        if (hm == null || hm.containsKey(key)) {
            return 0;
        }
        hm.put(key, val);
        return 1;
    }

    @Override
    public int putIfExists(String key, Object val) {
        if (hm == null || !hm.containsKey(key)) {
            return 0;
        }
        hm.put(key, val);
        return 1;
    }

    @Override
    public int remove(String key) {
        if (hm == null || !hm.containsKey(key)) {
            return 0;
        }
        hm.remove(key);
        return 1;
    }

    @Override
    public void forEach(IDictConsumer iConsumer) {
        for (Map.Entry<String, Object> entry : hm.entrySet()) {
            boolean isContinue = iConsumer.consumer(entry.getKey(), entry.getValue());
            if (!isContinue) {
                return;
            }
        }
    }

    @Override
    public String[] keys() {
        String[] ret = new String[hm.size()];
        int i = 0;
        for (String key : hm.keySet()) {
            ret[i] = key;
            i++;
        }
        return ret;
    }

    public String randomKey() {
        if (hm == null || hm.size() == 0) {
            return null;
        }
        for (String key : hm.keySet()) {
            return key;
        }
        return null;
    }

    @Override
    public String[] randomKeys(int limit) {
        if (hm == null || hm.size() == 0) {
            return null;
        }
        if (limit >= hm.size()) {
            return keys();
        }

        String[] ret = new String[limit];
        for (int i=0;i<limit;) {
            String s = randomKey();
            if (s != null) {
                ret[i] = s;
                i++;
            }
        }
        return ret;
    }

    @Override
    public String[] randomDistinctKeys(int limit) {
        HashMap<String, Boolean> hashMap = new HashMap<String, Boolean>();
        while (hashMap.size() < limit) {
            String k = randomKey();
            if (k != null) {
                hashMap.put(k, true);
            }
        }

        String[] ret = new String[limit];
        int i = 0;
        for (String k : hashMap.keySet()) {
            ret[i] = k;
            i++;
        }
        return ret;
    }

    @Override
    public void clear() {
        hm.clear();
    }

    @Override
    public Object[] diff(IDict[] dict) {
        return null;
    }

    @Override
    public Object[] union(IDict[] dicts) {
        return new Object[0];
    }
}
